package com.iteaj.iot.boot;

import cn.hutool.core.collection.CollectionUtil;
import com.iteaj.iot.*;
import com.iteaj.iot.boot.core.IotCoreConfiguration;
import com.iteaj.iot.business.ProtocolHandleFactory;
import com.iteaj.iot.event.FrameworkEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

import java.util.List;
import java.util.stream.Collectors;

@AutoConfigureAfter(IotCoreConfiguration.class)
public class IotApplication implements ApplicationRunner {

    private final IotThreadManager threadManager;
    private final IotCoreProperties coreProperties;
    private final ComponentFactory componentFactory;
    private final ApplicationContext applicationContext;
    private final ProtocolHandleFactory protocolHandleFactory;

    private static Logger logger = LoggerFactory.getLogger(IotApplication.class);

    public IotApplication(IotThreadManager threadManager, IotCoreProperties coreProperties, ComponentFactory componentFactory
            , ApplicationContext applicationContext, ProtocolHandleFactory protocolHandleFactory) {
        this.threadManager = threadManager;
        this.coreProperties = coreProperties;
        this.componentFactory = componentFactory;
        this.applicationContext = applicationContext;
        this.protocolHandleFactory = protocolHandleFactory;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        try {
            List<FrameworkEventListener> listeners = applicationContext
                    .getBeanProvider(FrameworkEventListener.class)
                    .stream().collect(Collectors.toList());

            // 构建框架各个组件管理器
            FrameworkManager.getInstance()
                    .build(listeners, this.threadManager
                    , this.componentFactory, this.protocolHandleFactory);

            // 注册组件
            applicationContext.getBeanProvider(FrameworkComponent.class).forEach(item -> {
                componentFactory.register(item);
            });

            // 注册协议处理器
            applicationContext.getBeanProvider(ProtocolHandle.class).forEach(item -> {
                protocolHandleFactory.register(item);
            });

            // 启动所有组件
            componentFactory.start(this);
        } catch (Exception e) {
            this.threadManager.close();
            this.componentFactory.close();

            List<LifeCycle> lifeCycles = applicationContext
                    .getBeanProvider(LifeCycle.class)
                    .stream().filter(item ->
                            !(item instanceof IotThreadManager)
                            && !(item instanceof ComponentFactory)
                            && !(item instanceof FrameworkComponent))
                    .collect(Collectors.toList());

            if(CollectionUtil.isNotEmpty(lifeCycles)) {
                lifeCycles.forEach(item -> {
                    try {
                        item.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                });
            }

            throw e;
        }

    }

}
